/**
 * ResponseAPIReceiver.java
 * ************************** 
 * @date May 13, 2011
 * @author Michele Tamburini
 * 
 * **************************
 */
package infrastructureAPI.backendGate.scriptsResponse;

import infrastructureAPI.APIMessages.ResponseMessage;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayDeque;
import java.util.Deque;

import messages.Message;

/**
 * Description: 
 * This class implements the ScriptResponseAPI interface.
 * Is able to register to the local rmiregistry and gives the
 * ability to a script to retrieve the reply messages from
 * the cloud.
 * It maintains a Dequeue of ResponseMessage(s). 
 *
 */
public class ResponseScriptAPIRemoteReceiver extends UnicastRemoteObject 
	implements ResponseScripAPIRemote {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	protected static ResponseScriptAPIRemoteReceiver responseReceiver;
	
	protected static Deque<ResponseMessage> receivedMessages;
	protected String registrationName;
	protected InetAddress registrationAddress;
	
	protected ResponseScriptAPIRemoteReceiver() throws RemoteException {
		super();
	}
	
	/**
	 * @param netMan
	 * @param incomingMsgClass
	 * @throws RemoteException 
	 * @throws UnknownHostException 
	 */
	public ResponseScriptAPIRemoteReceiver(InetAddress address ,String registrationName) 
			throws UnknownHostException, RemoteException {
		this.registrationName = registrationName;
		this.registrationAddress = address;
		receivedMessages = new ArrayDeque<ResponseMessage>();
		responseReceiver = new ResponseScriptAPIRemoteReceiver();
		registryToRmiregistry(address , registrationName);
	}
	
	/**
	 * Register this class to the local rmiregistry in order
	 * to receive the Message(s) from the cloud.
	 * @param address
	 * @param registrationName
	 * @return
	 * @throws UnknownHostException
	 * @throws RemoteException
	 */
	public boolean registryToRmiregistry(InetAddress address ,String registrationName) 
			throws UnknownHostException, RemoteException{
		boolean ret = true;
//		InetAddress host = InetAddress.getLocalHost();
		Registry registry = LocateRegistry.getRegistry(address.getHostAddress());
		
		if (System.getSecurityManager() == null) {
			System.setSecurityManager(new SecurityManager());
		}
		ResponseScripAPIRemote remoteObject_stub;
		UnicastRemoteObject.unexportObject(responseReceiver, true);
		remoteObject_stub = (ResponseScripAPIRemote) UnicastRemoteObject.exportObject(responseReceiver, 0);
		registry.rebind(registrationName, remoteObject_stub);
		
		System.out.println("Registered service "+registrationName+" " +
				"on node: "+address.getHostAddress()+" "+
				"into the registry: "+registry);
		return ret;		
	}

	@Override
	public boolean depositResponse(Message respMsg) throws RemoteException {
		synchronized (receivedMessages) {
			receivedMessages.add((ResponseMessage)respMsg);
			receivedMessages.notify();
		}
		return true;
	}
	
	public ResponseMessage waitForResponseMessage(){
		ResponseMessage msg = null;
		
		if(!receivedMessages.isEmpty()){
			synchronized (receivedMessages) {
				msg = receivedMessages.poll();
			}
			
		}else{
			while(msg == null){
				try {
					synchronized (receivedMessages) {
						receivedMessages.wait(0);
						if(!receivedMessages.isEmpty())
							msg = receivedMessages.poll();
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		return msg;
	}
	

}
